﻿using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace GenerateSignature
{
	class RSASignature
	{
		public RSAParameters key {get; private set;}
		private RSACryptoServiceProvider RSAalg;

		public RSASignature()
		{
			RSAalg = new RSACryptoServiceProvider();
		}

		// Make signature
		public RSAParameters MakeSig()
		{
			key = RSAalg.ExportParameters(true);

			return key;
		}


		// Sign
		public bool SignFile(RSAParameters sig, string fileToSign, string signedFile)
		{
			bool bResult = false;
			byte[] originalData;
			byte[] signedData;

			// Create a UnicodeEncoder to convert between byte array and string.
			UTF8Encoding ByteConverter = new UTF8Encoding();

			// check file
			if( File.Exists( fileToSign) )
			{
				originalData = ByteConverter.GetBytes(File.ReadAllText(fileToSign));
				signedData = HashAndSignBytes(originalData, key);

				// Output signed file
				File.WriteAllBytes(signedFile, signedData);

				// Verify Sign file
				if (VerifySignedHash(originalData, signedData, key))
				{
					Console.WriteLine("Verify OK");
				}
			}

			return bResult;
		}



		public void SignFile(RSAParameters privatekey, string filePath, Object hashObj)
		{
			// read file to stream byte (array of byte)
			
			// hash 
		}

		private byte[] HashAndSignBytes(byte[] DataToSign, RSAParameters Key)
		{
			try
			{
				RSAalg.ImportParameters(Key);

				// Hash and sign the data. Pass a new instance of SHA1CryptoServiceProvider 
				// to specify the use of SHA1 for hashing. 
				return RSAalg.SignData(DataToSign, new SHA1CryptoServiceProvider());
			}
			catch (CryptographicException e)
			{
				Console.WriteLine(e.Message);

				return null;
			}
		}
		
 		public bool VerifySignatureFile()
		{
			bool bResult = false;

			return bResult;
		}

		private bool VerifySignedHash(byte[] DataToVerify, byte[] SignedData, RSAParameters Key)
		{
			try
			{
				RSAalg.ImportParameters(Key);

				// Verify the data using the signature.  Pass a new instance of SHA1CryptoServiceProvider 
				// to specify the use of SHA1 for hashing. 
				return RSAalg.VerifyData(DataToVerify, new SHA1CryptoServiceProvider(), SignedData);

			}
			catch (CryptographicException e)
			{
				Console.WriteLine(e.Message);

				return false;
			}
		}
	}
}
